package ro.gillardon.business.priceservice.impl.plane;

import javax.ejb.Stateless;

import org.apache.log4j.Logger;

import ro.gillardon.business.exception.BusinessException;
import ro.gillardon.business.priceservice.PlanePriceService;
import ro.gillardon.commons.Conditions;
import ro.gillardon.commons.Offers;
import ro.gillardon.commons.logger.BTPLogger;
import ro.gillardon.commons.mot.plane.PlaneConditions;
import ro.gillardon.commons.mot.plane.PlaneOfferDetails;

/**
 * Implementation of plane specific price service.
 *
 * @author davidl
 */
@Stateless
public class PlanePriceServiceEJB implements PlanePriceService {

  private static final Logger LOG = Logger.getLogger(PlanePriceServiceEJB.class);

  /**
   * Instantiates a new plane price service ejb.
   */
  public PlanePriceServiceEJB() {
    //default constructor
  }

  /**
   * {@inheritDoc}
   *
   * @throws BusinessException
   */
  @Override
  public Offers<PlaneOfferDetails> getOffers(final Conditions conditions) throws BusinessException {

    PlaneConditions planeConditions = checkForCorrectType(conditions);

    String htmlResult = searchAndGetResults(planeConditions);

    return PlaneResultParser.parse(htmlResult, planeConditions);
  }

  /**
   * Main method where the parsing of the web page is happening , throws a {@link BusinessException}.
   *
   * @param conditions the entity which contains all the parameters to execute a query
   * @return After the search went through, the result table is returned, as raw HTML for later parsing
   * @throws BusinessException in case that there are no direct flights
   */
  private String searchAndGetResults(final PlaneConditions planeConditions) {

    try (PlaneNavigator navigator = new PlaneNavigator()) {
      navigator.navigateToPage(planeConditions);
      return navigator.getResults();
    } catch (BusinessException e) {
      BTPLogger.error(LOG, "There are no direct fights for the required input !. Details : " + e);
    }

    return null;

  }

  /**
   * Checks if the parameter type is of the allowed type, if is, converts it to the concrete type,<br/>
   * if not, throws a {@link BusinessException}.
   *
   * @param conditions the object whose type is checked
   * @return the concrete type
   * @throws BusinessException if not of the required type
   */
  private PlaneConditions checkForCorrectType(final Conditions conditions) throws BusinessException {
    if (!(conditions instanceof PlaneConditions)) {
      throw new BusinessException();
    }
    return (PlaneConditions) conditions;
  }
}
